package org.arl.modem.transportARQ;

public class TxTimer {
   private long infoTxtime;
   private long infoACKRxtime;
   private long firstPktTxtime;

   private long approxProcessingTime;
   private long twoWayDelay;
   private long blockTxTime;
   private TransportARQ tarq;
   private long delta;

   public TxTimer(long infoTxtime, TransportARQ tarq) {
      // super();
      this.infoTxtime = infoTxtime;
      this.tarq = tarq;
      infoACKRxtime = -1;
      firstPktTxtime = -1;
   }

   public long getInfoACKRxtime() {
      return infoACKRxtime;
   }

   public void setInfoACKRxtime(long infoACKRxtime) {
      this.infoACKRxtime = infoACKRxtime;
   }

   public long getFirstPktTxtime() {
      return firstPktTxtime;
   }

   public void setFirstPktTxtime(long firstPktTxtime) {
      this.firstPktTxtime = firstPktTxtime;
   }

   public void init(long firstTxtime) {
      twoWayDelay = infoACKRxtime - infoTxtime;
      firstPktTxtime = firstTxtime;
      approxProcessingTime = firstPktTxtime - infoACKRxtime;
      System.out.println("2way delay:" + twoWayDelay);
      System.out.println("approx proc time:" + approxProcessingTime);
      this.tarq.jarqDelta = (int) (this.tarq.jarqDelta + (approxProcessingTime) / 1000);
      System.out.println("JARQ delta(after proc time):" + this.tarq.jarqDelta);
   }

   public long getApproxProcessingTime() {
      return approxProcessingTime;
   }

   public long getBlockTxTime() {
      return blockTxTime;
   }

   public void setBlockTxTime(long blockTxTime) {
      this.blockTxTime = blockTxTime * 1000;
      if (tarq.k != 0) {

         // twodelay:pktdur:tarq.k:blocktxtime:processigtime:3893:556:1:1341000:732

         // setDelta((long) (((twoWayDelay) * 1000)//
         // // tarq.otherPRocTime) * 1000)
         // // / tarq.k - this.blockTxTime - tarq.jarqPktDur * 1000 * 2.5));
         // // / tarq.k - tarq.jarqPktDur * TransportARQ.blockSize * 1000 -
         // // tarq.jarqPktDur * 1000 * 2));
         // / tarq.k - tarq.jarqPktDur * TransportARQ.blockSize
         // * 1000
         // - tarq.jarqPktDur * 1000 - tarq.phyProcTime * 2 * 1000 -
         // tarq.otherPRocTime * 2 * 1000));
         // System.out.println("wakeupdelta(twoway/k - blocktx -pktdur*1.5*1000):"
         // + getDelta());
         // control packet

         // long deltaa = (twoWayDelay * 1000 - 300 * 1000) / tarq.k
         // // long deltaa = (twoWayDelay * 1000 + 300 * 1000) / tarq.k
         // - this.blockTxTime - tarq.jarqPktDur * 1000
         // - getApproxProcessingTime() * 1000;
         // long temp = (tarq.jarqPktdurControl + 300) * 1000;
         // System.out.println("temp:" + temp);
         // if (deltaa < temp)
         // deltaa = temp;
         // setDelta(deltaa);
         // System.out.println("delta: " + deltaa);
         System.out.println("twodelay:" + twoWayDelay);
         System.out.println("pktdur:" + tarq.jarqPktDur);
         System.out.println("pktdur control:" + tarq.jarqPktdurControl);
         System.out.println("blocktxtime:" + this.blockTxTime);
         System.out.println("processigtime:" + getApproxProcessingTime());
         tarq.mylog.fine("twodelay:" + twoWayDelay);
         tarq.mylog.fine("pktdur:" + tarq.jarqPktDur);
         tarq.mylog.fine("pktdur control:" + tarq.jarqPktdurControl);
         tarq.mylog.fine("blocktxtime:" + this.blockTxTime);
         tarq.mylog.fine("processigtime:" + getApproxProcessingTime());
         tarq.mylog.fine("thetha time:" + TransportARQ.THETA_TIME);
         // long deltaa = ((twoWayDelay - tarq.jarqPktdurControl -
         // tarq.jarqPktDur) * 1000) / tarq.k - this.blockTxTime
         // - tarq.jarqPktdurControl * 1000;
         // System.out.println("delta calculated old:" + deltaa);
         // tarq.mylog.fine("delta calculated old:" + deltaa);
         // deltaa = ((twoWayDelay - tarq.jarqPktdurControl - 200) * 1000) /
         // tarq.k - this.blockTxTime - 100 * tarq.blockSize
         // * 1000;
         //
         // System.out.println("delta calculated:" + deltaa);
         // tarq.mylog.fine("delta calculated:" + deltaa);
         //
         // long temp = (tarq.jarqPktdurControl + 300) * 1000;
         // System.out.println("temp:" + temp);
         // tarq.mylog.fine("temp:" + temp);
         // if (deltaa < temp)
         // deltaa = temp;

         // twodelay:1628
         // pktdur:670
         // pktdur control:357
         // blocktxtime:0
         // processigtime:715
         // thetha time:612
         // delta calculated:-324000
         // JARQ delta: -324000
         //
         // twoWayDelay = 1869;
         tarq.mylog.fine("twodelay new:" + twoWayDelay);
         long rx_procadjust = (tarq.rx_proctime_data - tarq.rx_proctime_control) / 1000;
         long deltaa = (twoWayDelay - tarq.jarqPktDur) * 1000 / tarq.k
               - this.blockTxTime - (long) Calculator.best_delta / 2 * 1000
               * 1000 - TransportARQ.THETA_TIME * 1000 - 50 * 1000;

         deltaa = deltaa + tarq.jarqPktDur * 1000;
         // (2wd - pktDuration)/K - blockDuration - switchingTime - delta/2 +
         // pktDuration
         // long deltaa = (twoWayDelay - tarq.jarqPktDur) * 1000 / tarq.k
         // - this.blockTxTime - tarq.jarqPktDur * 1000
         // - TransportARQ.THETA_TIME * 1000;
         deltaa = deltaa + TransportARQ.VARTIME_ADD * 1000
               - TransportARQ.VARTIME_SUB * 1000;
         System.out.println("delta calculated:" + deltaa);
         tarq.mylog.fine("delta calculated:" + deltaa);

         setDelta(deltaa);
         System.out.println("final JARQ delta: " + deltaa);
         tarq.mylog.fine("final JARQ delta: " + deltaa);
         // FIXME Rohit, Mar 19, 2012:cleanup this class remove the comments
         // - this.getApproxProcessingTime() * 1000 - tarq.jarqPktDur * 1000);
      } else
         setDelta(twoWayDelay * 1000 + 2 * tarq.jarqPktDur * 1000 + 2
               * getApproxProcessingTime() * 1000);
   }

   public long getTwoWayDelay() {
      return twoWayDelay;
   }

   public void setTwoWayDelay(long twoWayDelay) {
      this.twoWayDelay = twoWayDelay;
   }

   public long getDelta() {
      return delta;
   }

   public void setDelta(long delta) {
      this.delta = delta;
   }
}
